package com.tongtech.system.service.impl;

import com.tongtech.common.core.utils.DateUtils;
import com.tongtech.common.datascope.annotation.DataScope;
import com.tongtech.common.security.utils.SecurityUtils;
import com.tongtech.system.api.domain.SysUser;
import com.tongtech.system.api.model.LoginUser;
import com.tongtech.system.domain.*;
import com.tongtech.system.domain.vo.UserWorkOrderVo;
import com.tongtech.system.enums.WorkOrderStatusType;
import com.tongtech.system.mapper.WorkOrderMapper;
import com.tongtech.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 工单管理 服务实现
 *
 * @author xingyc
 */
@Service
public class WorkOrderServiceImpl implements IWorkOrderService
{
    @Autowired
    private WorkOrderMapper workOrderMapper;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IProductService productService;

    @Autowired
    private IWorkOrderCategoryService workOrderCategoryService;

    @Autowired
    private IWorkOrderSupportService workOrderSupportService;

    /**
     * 查询工单管理数据
     *
     * @param workOrder 工单信息
     * @return 工单信息集合
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<WorkOrder> selectWorkOrderList(WorkOrder workOrder)
    {
        List<WorkOrder> list = workOrderMapper.selectWorkOrderList(workOrder);
        if(!CollectionUtils.isEmpty(list)){
            list.stream().forEach(wo -> {
                fillInfo(wo);
            });
        }
        return list;
    }

    /**
     * 根据支持人员，查询工单管理数据
     *
     * @param workOrder 工单信息
     * @return 工单信息集合
     */
    @Override
    public List<WorkOrder> selectWorkOrderListBySupport(WorkOrder workOrder)
    {
        List<WorkOrder> list = workOrderMapper.selectWorkOrderListBySupport(workOrder);
        return list;
    }

    @Override
    public Map<String, Map<String, WorkOrder>> selectPlans(String startDate, String endDate) {
        Map<String, Map<String, WorkOrder>> map = new HashMap<String, Map<String, WorkOrder>>();
        List<SysUser> userList = userService.selectUserList(new SysUser());
        if(!CollectionUtils.isEmpty(userList)){
            userList.stream().forEach(user -> {
                Long userId = user.getUserId();
                Date startTime = DateUtils.parseDate(startDate);
                Date endTime = DateUtils.parseDate(endDate);
                WorkOrder queryWorkOrder = new WorkOrder();
                queryWorkOrder.setStartTime(startTime);
                queryWorkOrder.setEndTime(endTime);
                queryWorkOrder.setSupportPersonnelId(userId);
                List<WorkOrder> workOrders = selectWorkOrderListBySupport(queryWorkOrder);
                UserWorkOrderVo userWorkOrderVo = new UserWorkOrderVo();
                userWorkOrderVo.setUserId(userId);
                //根据查询数据构建日期范围内的数据
                Map<String, WorkOrder> workOrderMap = buildWorkOrders(startTime, endTime, workOrders);
                map.put("" + userId, workOrderMap);
            });
        }
        return map;
    }
    private Map<String, WorkOrder> buildWorkOrders(Date startDate, Date endDate, List<WorkOrder> workOrders){
        Map<String, WorkOrder> map = new ConcurrentHashMap<String, WorkOrder>();
        if (!CollectionUtils.isEmpty(workOrders)) {
            workOrders.stream().forEach(wo ->{
                Date woStartTime = wo.getStartTime();
                Date woEndTime = wo.getEndTime();
                //判断开始时间和结束时间在查询时间范围内，还有有左交叉或右交叉
                if(woStartTime.getTime() < startDate.getTime()){
                    woStartTime = startDate;
                }
                if(endDate.getTime() < woEndTime.getTime()){
                    woEndTime = endDate;
                }
                //判断开始时间和结束时间，差几天，是周几。 1：周日 2：周一，以此类推
                int startDatOfWeek = DateUtils.dayOfWeek(woStartTime) -1;
                map.put("" + startDatOfWeek, wo);
                //计算endTime 和 startTime差几天，补上期间的数据
                int endDatOfWeek = DateUtils.dayOfWeek(woEndTime) -1;
                if(endDatOfWeek - startDatOfWeek != 0){
                    for(int i = startDatOfWeek ; i <= endDatOfWeek; i++){
                        map.put("" + i, wo);
                    }
                }
            });
        }
        //最后判断，哪些天没有放进去，重新补充为null
        for(int i = 0 ; i <= 6; i++){
            WorkOrder wo = map.get("" + i);
            if(Objects.isNull(wo)){
                map.put("" + i, new WorkOrder());
            }
        }
        return map;
    }

    private void fillInfo(WorkOrder workOrder){
        Long projectId = workOrder.getProjectId();
        if(Objects.nonNull(projectId)){
            Project project = projectService.selectProjectById(projectId);
            if(Objects.nonNull(project)){
                workOrder.setProjectName(project.getName());
            }
        }
        Long productId = workOrder.getProductId();
        if(Objects.nonNull(productId)){
            Product product = productService.selectProductById(productId);
            if(Objects.nonNull(product)){
                workOrder.setProductName(product.getProductName());
            }
        }
        Long type = workOrder.getType();
        if(Objects.nonNull(type)){
            WorkOrderCategory category = workOrderCategoryService.selectWorkOrderCategoryById(type);
            if(Objects.nonNull(category)){
                workOrder.setTypeName(category.getWorkOrderCategoryName());
            }
        }
        Long marketerId = workOrder.getMarketerId();
        if(Objects.nonNull(marketerId)){
            SysUser user = userService.selectUserById(marketerId);
            if(Objects.nonNull(user)){
                workOrder.setMarketerName(user.getNickName());
            }
        }
        Date startTime = workOrder.getStartTime();
        if(Objects.nonNull(startTime)){
            Date endTime = workOrder.getEndTime();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String start = sdf.format(startTime);
            String end = sdf.format(endTime);
            String[] dateRange = new String[]{start, end};
            workOrder.setDateRange(dateRange);
        }
        //获取支持人员列表
        Long workOrderId = workOrder.getWorkOrderId();
        WorkOrderSupport workOrderSupport = new WorkOrderSupport();
        workOrderSupport.setWorkOrderId(workOrderId);
        List<WorkOrderSupport> workOrderSupports = workOrderSupportService.selectWorkOrderSupportList(workOrderSupport);
        if(!CollectionUtils.isEmpty(workOrderSupports)){
            workOrder.setSupports(workOrderSupports);
        }
    }

    /**
     * 根据工单ID查询信息
     *
     * @param workOrderId 工单ID
     * @return 工单信息
     */
    @Override
    public WorkOrder selectWorkOrderById(Long workOrderId)
    {
        WorkOrder workOrder = workOrderMapper.selectWorkOrderById(workOrderId);
        if(Objects.nonNull(workOrder)){
            fillInfo(workOrder);
        }
        return workOrder;
    }

    private void formatStartEndTime(WorkOrder workOrder){
        if(Objects.nonNull(workOrder)){
            Date startTime = workOrder.getStartTime();
            if(Objects.nonNull(startTime)){
                Date endTime = workOrder.getEndTime();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String start = sdf.format(startTime);
                String end = sdf.format(endTime);
                String[] dateRange = new String[]{start, end};
                workOrder.setDateRange(dateRange);
            }
        }
    }

    /**
     * 新增保存工单信息
     *
     * @param workOrder 工单信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertWorkOrder(WorkOrder workOrder)
    {
        if(Objects.nonNull(workOrder)){
            String[] dataRange = workOrder.getDateRange();
            formatStartEndTime(dataRange, workOrder);

            //补充userId和deptId，用于数据权限。
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if(Objects.nonNull(loginUser)){
                SysUser sysUser = loginUser.getSysUser();
                Long userId = sysUser.getUserId();
                Long deptId = sysUser.getDeptId();
                workOrder.setUserId(userId);
                workOrder.setDeptId(deptId);
            }
        }
        //判断是否已经选择了支持人员，若已经选择，则工单状态变成已分配状态
        List<WorkOrderSupport> supports = workOrder.getSupports();
        if(Objects.nonNull(supports)){
            workOrder.setOrderStatus(WorkOrderStatusType.ALLOCATED.getCode());
        }
        int result = workOrderMapper.insertWorkOrder(workOrder);
        //保存支持人员列表
        saveWorkOrderSupports(workOrder);
        return result;
    }

    private void formatStartEndTime(String[] dataRange, WorkOrder workOrder){
        if(dataRange != null && dataRange.length > 0){
            String startDate = dataRange[0];
            String endDate = dataRange[1];
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                workOrder.setStartTime(sdf.parse(startDate));
                workOrder.setEndTime(sdf.parse(endDate));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 修改保存工单信息
     *
     * @param workOrder 工单信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateWorkOrder(WorkOrder workOrder)
    {
        if(Objects.nonNull(workOrder)){
            String[] dataRange = workOrder.getDateRange();
            formatStartEndTime(dataRange, workOrder);

            //校验orderStatus=4(已完成)，已完成状态要扣项目的现场人天
            String orderStatus = workOrder.getOrderStatus();
            if(Objects.equals(WorkOrderStatusType.COMPLETED.getCode(), orderStatus)){
                Long projectId = workOrder.getProjectId();
                Date startTime = workOrder.getStartTime();
                Date endTime = workOrder.getEndTime();
                Long days = DateUtils.getDaysDifference(startTime, endTime);

                Project project = projectService.selectProjectById(projectId);
                if(Objects.nonNull(project)){
                    Integer residueDays = project.getResidueDays();
                    if(Objects.nonNull(residueDays)){
                        residueDays = residueDays - (days.intValue() + 1);
                    }
                    Project updateProject = new Project();
                    updateProject.setProjectId(projectId);
                    updateProject.setResidueDays(residueDays);
                    projectService.updateProject(updateProject);
                }
            }
        }
        int result = workOrderMapper.updateWorkOrder(workOrder);
        saveWorkOrderSupports(workOrder);
        return result;
    }

    @Transactional
    public void saveWorkOrderSupports(WorkOrder workOrder){
        //将新选择的支持人员列表保存到工单支持人员表
        Long workOrderId = workOrder.getWorkOrderId();
        //先删除原有的数据
        workOrderSupportService.deleteWorkOrderSupportByWorkOrderId(workOrderId);
        if(Objects.nonNull(workOrderId)){
            List<WorkOrderSupport> supports = workOrder.getSupports();
            if(!CollectionUtils.isEmpty(supports)){
                supports.stream().forEach(item ->{
                    item.setWorkOrderId(workOrderId);
                    //补充userId和deptId，用于数据权限。
                    LoginUser loginUser = SecurityUtils.getLoginUser();
                    if(Objects.nonNull(loginUser)){
                        SysUser sysUser = loginUser.getSysUser();
                        Long userId = sysUser.getUserId();
                        Long deptId = sysUser.getDeptId();
                        item.setUserId(userId);
                        item.setDeptId(deptId);
                    }
                    workOrderSupportService.insertWorkOrderSupport(item);
                });
            }
        }
    }

    /**
     * 删除工单管理信息
     *
     * @param deptId 工单ID
     * @return 结果
     */
    @Override
    public int deleteWorkOrderById(Long deptId)
    {
        return workOrderMapper.deleteWorkOrderById(deptId);
    }
}
